const AppError = require('./../utils/appError');
// mongodb带的错误
const handleCastErrorDB = (err) => {
    const message = `Invalid ${err.path}: ${err.value}`;
    return new AppError(message, 400);
}
// 重复提交key的错误
const handleDuplicateFieldsDB = err => {
    // 匹配两个//的错误
    const value = err.errmsg.match(/(["'])(\\?.)*?\1/)[0];
    console.log(value);

    const message = `Duplicate field value: ${value}. Please use another value!`;
    return new AppError(message, 400);
};
// 验证错误
const handleValidationErrorDB = err => {
    const errors = Object.values(err.errors).map(el => el.message);

    const message = `Invalid input data. ${errors.join('. ')}`;
    return new AppError(message, 400);
};
// jwt token 错误
const handleJWTError = err=>{
    const message = `Invalid token,请重新登录`;
    return  new AppError(message, 401);
}

const handleJWTExpiredError = err=>{
    const message = `token超时,请重新登录`;
    return  new AppError(message, 401);
}

const sendErrorDev = (err, res) => {
    res.status(err.statusCode).json({
        status: err.status,
        message: err.message,
        error: err,
        stack: err.stack
    })
}
const sendErrorProd = (err, res) => {
    // 可操作错误发送到前台 比如查找了不存在的ID 多余的页码等
    if (err.isOperational) {
        res.status(err.statusCode).json({
            status: err.status,
            message: err.message
        })
        // 程序或者未知错误 比如来自数据库的错误
    } else {
        console.log('ERROR', err);

        // 2. 发送可搜集信息
        res.status(500).json({
            status: 'error',
            err: err,
            message: 'Something went very wrong'
        })
    }
}

module.exports = (err, req, res, next) => {
    //console.log(err.statusCode,'进来了吗',)
    err.statusCode = err.statusCode || 500;
    err.status = err.status || 'error';
    if (process.env.NODE_ENV === 'development') {
        sendErrorDev(err, res);
    } else if (process.env.NODE_ENV === 'production') {
        // let error = { ...err }; 把那么给解构掉了？
        let error = err;
        // 
        console.log(error, '??')
        if (error.name === 'CastError') error = handleCastErrorDB(error);
        if (error.code === 11000) error = handleDuplicateFieldsDB(error);
        if (error.name === 'JsonWebTokenError') error = handleJWTError(error);
        if (error.name === 'TokenExpiredError') error = handleJWTExpiredError(error);
        sendErrorProd(error, res);
    }

}